import { _decorator, Animation, Color, Label, Node, ProgressBar, sp, Sprite, SpriteFrame, tween, Tween, Vec2 } from 'cc';
import { ListRender } from '../../Basic/Component/ListRender';
import { autoComp, autoNode } from '../../Basic/Manager/BaseManager';
import { AudioManager } from '../../Basic/Manager/AudioManager';
import { SoundCode } from '../../Basic/Config/BaseEnum';
import { ItemData } from '../Config/GlobalModel';
import { EnemyItem } from './EnemyItem';
import { Tool } from '../../Util/Tool';
import { EventManager } from '../../Basic/Manager/EventManager';
import { GameEventType } from '../Config/GameEnum';
import { GridType } from '../../Data/Types';
import { MainModel_Ins } from './MainModel';
import { DataMgr } from '../../Basic/Manager/DataManager';
import { UpperModel_Ins } from './UpperModel';

const { ccclass, property } = _decorator;
@ccclass('TowerItem')
export class TowerItem extends ListRender {
  @autoNode()
  dizuo: Node;
  @autoComp(Animation)
  item: Animation;
  @autoComp(Sprite)
  sp: Sprite;
  @autoNode()
  head: Node;
  // @autoComp(sp.Skeleton)
  // spine: sp.Skeleton;
  @autoComp(ProgressBar)
  bar_hp: ProgressBar;
  @autoComp(Sprite)
  bar: Sprite;
  @autoComp(Label)
  lab_bar: Label;
  @autoComp(Label)
  lab: Label;
  data: ItemData;
  gridPos: number[] = [];
  curState: string = '';
  protected onLoad(): void {
    // this.spine.setCompleteListener(this.onSpineComplete.bind(this));
  }
  dataChanged(): void {
    // this.spine.node.active = false;
    const tbData = DataMgr.tables.TbArchitecture.get(this.data.id);
    const attr = tbData.attri[this.data.level - 1];
    switch (this.data.type) {
      case GridType.GodWall:
        this.item.node.active = false;
        this.dizuo.active = false;
        break;
      case GridType.Door:
      case GridType.Tower:
      case GridType.Other:
        MainModel_Ins.loadDynamicRes<SpriteFrame>(`resources/sprite/${attr.img}/spriteFrame`).then((spr) => {
          this.sp.spriteFrame = spr;
        });
        this.item.node.active = true;
        this.head.active = this.data.id === 1001;
        this.dizuo.active = this.data.type === GridType.Tower;
        break;
    }

    this.data.hpMax = attr.hp;
    this.data.hp = this.data.hpMax;
    this.data.atkMax = attr.atk;
    this.data.atk = this.data.atkMax;
    this.data.levelCost = attr.cost;
    this.data.levelMax = tbData.attri.length;
    this.data.coin = attr.coin;
    this.atkSpace = attr.space > 0 ? 1 / attr.space : 1;
    this.item.node.angle = 0;
    // this.lab.string = `${this.data.type}`;
    this.atkTarget = null;
    // if (this.spine.node.active) this.playAni('Idle5');
    this.refreshHp();
  }

  playAni(state: string) {
    if (this.curState === state) return;
    this.curState = state;
    let loop = false;
    switch (this.curState) {
      case 'Idle5':
      case 'Walk':
      case 'Walk2':
        loop = true;
        break;
    }
    // this.spine.setAnimation(0, this.curState, loop);
  }

  onSpineComplete(t: sp.spine.TrackEntry) {
    switch (t.animation.name) {
      case 'Attack':
      case 'Attack2':
        this.playAni('Idle5');
        break;
    }
  }

  get IsDeah() {
    return this.data.hp <= 0;
  }

  hirt(value: number) {
    this.data.hp -= value;
    this.data.hp = this.data.hp <= 0 ? 0 : this.data.hp;
    this.refreshHp();
    if (this.IsDeah) this.die();
  }

  die() {
    // this.playAni('Idle5');
    console.log('防御塔摧毁');
    EventManager.Ins().emit(GameEventType.MAIN_RECOVER, this.node);
  }

  // timer_hp: NodeJS.TimeOut;
  /** 刷新血量 */
  refreshHp() {
    this.lab_bar.string = `${this.data.hp}/${this.data.hpMax}`;
    Tween.stopAllByTarget(this.bar_hp);
    let rate = this.data.hp / this.data.hpMax;
    rate = rate <= 0 ? 0 : rate;
    rate = rate >= 1 ? 1 : rate;
    this.bar_hp.node.active = this.data.type != GridType.GodWall;
    EventManager.Ins().emit(GameEventType.MAIN_REPAIR);
    tween(this.bar_hp)
      .to(0.2, { progress: rate })
      .delay(0.2)
      .call(() => {
        this.bar_hp.node.active = false;
      })
      .start();
  }

  private atkTarget: EnemyItem = null;
  private atkSpace: number = 1;
  private atkCount: number = 0;
  /** 检测攻击对象 */
  checkAtkTarget(targetArr: EnemyItem[]) {
    let target = null;
    let minDis = this.data.atkRange * 100;
    const towerPos = new Vec2(this.node.getPosition().x, this.node.getPosition().y);
    targetArr.forEach((enemy) => {
      const dis = Tool.Vec2Sub(new Vec2(enemy.node.getPosition().x, enemy.node.getPosition().y), towerPos);
      if (dis.length() <= minDis) {
        minDis = dis.length();
        target = enemy;
      }
    });
    this.atkTarget = target;
  }

  attack() {
    const atkTarget = this.atkTarget;
    const atkValue = this.data.atk;
    const bPos = this.node.getPosition().clone();
    const ePos = atkTarget.node.getPosition().clone();
    this.item.stop();
    this.item.play('attack');
    AudioManager.Singleton.playSound(SoundCode.Shoot);
    // this.playAni(Math.random() > 0.5 ? 'Attack2' : 'Attack');
    EventManager.Ins().emit(GameEventType.MAIN_CREATE_BUTTLE, this.data.level - 1, bPos, ePos, () => {
      if (atkTarget.IsDeah) return;
      else atkTarget.hirt(atkValue);
    });
  }

  upper() {
    this.data.level++;
    const tbData = DataMgr.tables.TbArchitecture.get(this.data.id);
    const attr = tbData.attri[this.data.level - 1];
    this.data.hpMax = attr.hp;
    this.data.hp = this.data.hpMax;
    this.data.atkMax = attr.atk;
    this.data.atk = this.data.atkMax;
    this.data.levelCost = attr.cost;
    this.data.coin = attr.coin;
    this.atkSpace = attr.space > 0 ? 1 / attr.space : 1;
    this.refreshHp();

    MainModel_Ins.loadDynamicRes<SpriteFrame>(`resources/sprite/${attr.img}/spriteFrame`).then((spr) => {
      this.sp.spriteFrame = spr;
    });
    // switch (this.data.type) {
    //   case GridType.Door:
    //     MainModel_Ins.loadDynamicRes<SpriteFrame>(`resources/sprite/door_${this.data.level - 1}/spriteFrame`).then((spr) => {
    //       this.sp.spriteFrame = spr;
    //     });
    //     break;
    //   case GridType.Other:
    //     MainModel_Ins.loadDynamicRes<SpriteFrame>(`resources/sprite/bed_${this.data.level - 1}/spriteFrame`).then((spr) => {
    //       this.sp.spriteFrame = spr;
    //     });
    //     break;
    // }
  }

  repair() {
    this.data.hp += 5;
    this.data.hp = this.data.hp >= this.data.hpMax ? this.data.hpMax : this.data.hp;
    this.refreshHp();
  }

  protected update(dt: number): void {
    if (this.IsDeah) return;
    if (this.atkTarget === null || this.atkTarget.node.parent === null) return;

    const ePos = this.atkTarget.node.getPosition().clone();
    const bPos = this.node.getPosition().clone();

    const angle = (Math.atan2(ePos.y - bPos.y, ePos.x - bPos.x) * 180) / Math.PI;
    this.item.node.angle = angle - 90;

    this.atkCount += dt;
    if (this.atkCount >= this.atkSpace) {
      this.atkCount = 0;
      this.attack();
    }
  }

  /** 塔、门、空格可交互 */
  onClickSelf() {
    if (this.data.type === GridType.GodWall || this.data.level >= this.data.levelMax) return;
    AudioManager.Singleton.playSound(SoundCode.BtnClick);
    UpperModel_Ins.Show({ item: this });
  }
}
